import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;

import javax.tools.JavaCompiler;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

import org.codehaus.janino.JavaSourceClassLoader;
import org.codehaus.janino.util.resource.Resource;
import org.codehaus.janino.util.resource.ResourceFinder;

public class CompilerTest {
	public static void main(String[] args) throws Exception {
		janino();
	}

	public static void javaxcompiler() {
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		SimpleJavaFileObject fromString = new JavaSourceFromString("testCode",
				"class olli {}");
		CompilationTask task = compiler.getTask(null, null, null, null, null,
				Arrays.asList(fromString));
		Boolean call = task.call();
		System.out.println(call);
	}

	public static void janino() throws Exception {

		// Sample code that reads, scans, parses, compiles and loads
		// "A.java" and "B.java", then instantiates an object of class
		// "A" and invokes its "run()" method.
		ClassLoader cl = new JavaSourceClassLoader(CompilerTest.class.getClassLoader(),
				new ResourceFinder() {

					@Override
					public Resource findResource(String resourceName) {
						final String fileName = "pkg1/A.java";
						final String message = "Janino works on GAE";
						if (resourceName.equals(fileName)) {
							final String resource = "package pkg1;\n\n"
									+ "					public class A implements Runnable {\n"
									+ "					    public void run() {\n"
									+ "					        System.out.println(\""
									+ message + "\");\n" + "					    }\n"
									+ "					}\n";
							return new Resource() {

								@Override
								public String getFileName() {
									return fileName;
								}

								@Override
								public long lastModified() {
									// TODO Auto-generated method stub
									return 0;
								}

								@Override
								public InputStream open() throws IOException {
									return new ByteArrayInputStream(resource
											.getBytes());
								}

							};

						} else {
							return null;
						}
					}

				}, null);

		// Load class A from "srcdir/pkg1/A.java", and also its superclass
		// B from "srcdir/pkg2/B.java":
		Object o = cl.loadClass("pkg1.A").newInstance();

		// Class "B" implements "Runnable", so we can cast "o" to
		// "Runnable".
		((Runnable) o).run(); // Prints "HELLO" to "System.out".
	}

	public static class JavaSourceFromString extends SimpleJavaFileObject {
		final String code;

		public JavaSourceFromString(String name, String code) {
			super(URI.create("string:///" + name.replace('.', '/')
					+ Kind.SOURCE.extension), Kind.SOURCE);
			this.code = code;
		}

		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors) {
			return code;
		}
	}
}